﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using MJunction;

namespace L2Tools.Model
{
    public class L2SubDirectory
    {
        #region Attribute
        private readonly L2Directory l2Directory;
        private readonly string name;
        private bool selected;
        #endregion

        #region Constructor
        internal L2SubDirectory(L2Directory l2Directory, string name)
        {
            this.l2Directory = l2Directory;
            this.name = name;
        }
        #endregion

        #region Property
        private DirectoryInfo Source
        {
            get
            {
                if (l2Directory.L2DirectoryPath != null)
                {
                    return new DirectoryInfo(l2Directory.L2DirectoryPath + @"\" + name);
                }
                else
                {
                    return null;
                }
            }
        }
        private DirectoryInfo Backup
        {
            get
            {
                if (l2Directory.L2DirectoryPath != null)
                {
                    return new DirectoryInfo(
                        l2Directory.L2DirectoryPath + L2Directory.Backup + @"\" + name);
                }
                else
                {
                    return null;
                }
            }
        }
        private DirectoryInfo Ramdisk
        {
            get
            {
                if (l2Directory.RamdiskDirectoryPath != null)
                {
                    return new DirectoryInfo(
                        l2Directory.RamdiskDirectoryPath + @"\" + name);
                }
                else
                {
                    return null;
                }
            }
        }
        public bool Selected
        {
            get
            {
                return selected;
            }
            set
            {
                selected = value;
            }
        }
        public bool Exists
        {
            get
            {
                if (Source != null && Source.Exists)
                {
                    return true;
                }
                else if (Ramdisk != null && Ramdisk.Exists)
                {
                    return true;
                }
                else if (Backup != null && Backup.Exists)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        #endregion

        #region Method
        internal MirroringJunction CreateMirroringJunction()
        {
            if (Source == null)
            {
                // 例外処理はとりあえず放置
                throw new Exception("L2SubDirectory " + name + " source is null.");
            }
            if (selected)
            {
                return new MirroringJunction(name, Source.FullName);
            }
            else
            {
                return null;
            }
        }
        internal MirroringJunction CreateMirroringJunctionForce()
        {
            if (Source == null)
            {
                // 例外処理はとりあえず放置
                throw new Exception("L2SubDirectory " + name + " source is null.");
            }
            return new MirroringJunction(name, Source.FullName);
        }
        public L2DirectoryInfo Count()
        {
            if (Ramdisk != null && Ramdisk.Exists)
            {
                return DeepCount(Ramdisk);
            }
            else if (Source != null && Source.Exists && !JunctionPoint.Exists(Source.FullName))
            {
                return DeepCount(Source);
            }
            else if (Backup != null && Backup.Exists)
            {
                return DeepCount(Backup);
            }
            else
            {
                return new L2DirectoryInfo();
            }
        }

        private L2DirectoryInfo DeepCount(DirectoryInfo dir)
        {
            L2DirectoryInfo result = new L2DirectoryInfo();
            foreach (DirectoryInfo sub in dir.GetDirectories())
            {
                L2DirectoryInfo subInfo = DeepCount(sub);
                result.FileCount += subInfo.FileCount;
                result.Size += subInfo.Size;
            }
            foreach (FileInfo file in dir.GetFiles())
            {
                result.FileCount++;
                result.Size += file.Length;
            }

            return result;
        }
        #endregion
    }
}
